home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / (A)P / (A)P1.ADF / spin3 / spin3.c < prev   
C/C++ Source or Header  |  1987-05-25  |  16KB  |  506 lines

  1. /* ---------------------------- S p i n 3 . c ------------------------------ */
  2. /*  This is a simple routine that creates some spinning cubes and transforms */
  3. /*  them into op-art.  It is a good example of how to take total control of  */
  4. /*  of the screen for graphics and create a double buffered display (with    */
  5. /*  color tables that can be changed!)                                       */
  6. /*  I place it in the public domain so long as no one uses it for profit and */
  7. /*  these comments remain with the source code.                              */
  8. /*      Ronald Peterson     PeopleLink:  OPS448   BIX: rpeterson             */
  9. /*---------------------------------------------------------------------------*/
  10.  
  11. /*--- INCLUDE's ------------------------------------------------------------ */
  12.  
  13. #include "stdio.h"
  14. #include "math.h"
  15. #include "limits.h"
  16. #include "exec/types.h"
  17. #include "graphics/gfx.h"
  18. #include "graphics/gfxmacros.h"
  19. #include "graphics/copper.h"
  20. #include "graphics/view.h"
  21. #include "graphics/regions.h"
  22. #include "graphics/clip.h"
  23. #include "exec/exec.h"
  24. #include "graphics/gfxbase.h"
  25. #include "graphics/rastport.h"
  26. #include "hardware/custom.h"
  27. #include "hardware/dmabits.h"
  28.  
  29. /*--- DEFINE's --------------------------------------------------------------*/
  30.  
  31. #define DEPTH 4
  32. #define COLORS 16    /* COLORS = 2**DEPTH */
  33. #define WIDTH 320
  34. #define HEIGHT 200
  35. #define NOT_ENOUGH_MEMORY -1000
  36.  
  37. /*--- GLOBAL variable definitions -------------------------------------------*/
  38.  
  39. struct View v;
  40. struct ViewPort vp;
  41. struct ColorMap *cm;  /* pointer to colormap structure, dynamic alloc */
  42. struct RasInfo ri;
  43. struct BitMap b;  /* note:  Due to the static allocation of a structure
  44.                    * accessed directly by the custom chips, this program
  45.                    * will only work if it resides entirely within the lower
  46.                    * 512k bytes of memory (CHIP memory)
  47.                    */
  48. struct BitMap b2;  /* second bitmap for double buffering */
  49. struct cprlist *lof1;  /* copper list pointers for double buffer */
  50. struct cprlist *lof2;
  51. struct cprlist *shf1;
  52. struct cprlist *shf2;
  53. struct CopList *Disp1, *Disp2;
  54. extern int Enable_Abort;
  55.  
  56. /*--- RastPort variables ----------------- */
  57.  
  58. PLANEPTR rastpoint, rastpoint2;
  59.  
  60. struct RastPort rp;
  61. struct RastPort rp2;
  62.  
  63. WORD areabuffer[250];
  64. struct TmpRas tmpras;
  65. struct AreaInfo myAreaInfo;
  66.  
  67. WORD areabuffer2[250];
  68. struct TmpRas tmpras2;
  69. struct AreaInfo myAreaInfo2;
  70.  
  71. /*--- My global variables */
  72.  
  73. extern struct Custom custom;  /* so that graphics macros work.  OFF_SPRITE */
  74.  
  75. extern struct ColorMap *GetColorMap();
  76. struct GfxBase *GfxBase;
  77. struct View *oldview;  /* save pointer to old view so can restore */
  78.  
  79. USHORT colortable[COLORS] = {0x0000, 0x0222,
  80.       0x0444, 0x0555, 0x0666, 0x0777, 0x0888, 0x0999, 0x0AAA, 0x0BBB, 0x0CCC,
  81.       0x0DDD, 0x0EEE, 0x0FFF, 0x0005, 0x000A};
  82.      /* set colors shades of white, Light blue, Medium blue */
  83.      /*                  0-13          14            15   */
  84. USHORT j, tmp;
  85. UBYTE *displaymem;
  86. UWORD *colorpalette;
  87.  
  88. /*--- Start of main routine -------------------------------------------------*/
  89.  
  90. main()
  91. {
  92. SHORT bx[30], by[30], bz[30], dx[30], dy[30], dz[30];
  93. SHORT size[30], xminus, xplus, yminus, yplus;
  94. SHORT cx, cy, cz, half, nobj;
  95. LONG i;
  96. SHORT k, icol[30], icol2, xhalf, dxhalf, ncol;
  97. static SHORT icl[8] = {256, 16, 1, 4096, -256, -16, -1 ,-4096};
  98. static float scl[7] = {1.0, 1.138, 1.276, 1.414, 1.276, 1.138, 1.0};
  99.  
  100. /*--- Open graphics and Intuition libraries */
  101.  
  102.    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
  103.    if(GfxBase == NULL)exit(1);
  104.    oldview = GfxBase->ActiView;         /* Save current view to restore later */
  105.                                         /* Steals screen from Intuition if    */
  106.                                         /* started from WorkBench.            */
  107.  
  108. /*--- Initialize graphics structures and create double buffered display. */
  109.  
  110.    OFF_SPRITE;        /* turn off pointer (sprites off) */
  111.    InitView(&v);      /* initialize view */
  112.    InitVPort(&vp);    /* initialize viewport */
  113.    v.ViewPort = &vp;  /* link view into viewport */
  114.  
  115.    InitBitMap(&b,DEPTH,WIDTH,HEIGHT);  /* Init two bitmaps for double        */
  116.    InitBitMap(&b2,DEPTH,WIDTH,HEIGHT); /* buffering (for RasInfo & RastPort) */
  117.  
  118.    ri.BitMap = &b;         /* Init RasInfo structure */
  119.    ri.RxOffset = 0;
  120.    ri.RyOffset = 0;
  121.    ri.Next = NULL;
  122.  
  123.    vp.DWidth = WIDTH;      /* Specify ViewPort characteristics. */
  124.    vp.DHeight = HEIGHT;
  125.    vp.RasInfo = &ri;
  126.  
  127.    cm = GetColorMap(COLORS); /* Init color table (16 slots since 4 planes deep */
  128.    vp.ColorMap = cm;       /* Set ViewPort pointer to my colors */
  129.    LoadRGB4(&vp,colortable,COLORS);  /* Set viewport colors */
  130.  
  131.    for(i=0; i<DEPTH; i++)  /* Allocate RAM for bitmaps. */
  132.    {
  133.       b.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
  134.       if(b.Planes[i] == NULL)exit(NOT_ENOUGH_MEMORY);
  135.       b2.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
  136.       if(b2.Planes[i] == NULL)exit(NOT_ENOUGH_MEMORY);
  137.    }
  138.  
  139.    ri.BitMap = &b;
  140.    MakeVPort(&v,&vp);      /* construct copper instr (prelim) list     */
  141.    MrgCop(&v);             /* merge prelim lists together into a real  */
  142.                            /* copper list in the view structure        */
  143.    lof1 = v.LOFCprList;    /* store pointers to copper lists for bitmap 1 */
  144.    shf1 = v.SHFCprList;
  145.    Disp1 = v.ViewPort->DspIns; /* To get color map to change properly */
  146.  
  147.    v.LOFCprList = 0;
  148.    v.SHFCprList = 0;
  149.    v.ViewPort->DspIns = 0;
  150.  
  151.    ri.BitMap = &b2;
  152.    MakeVPort(&v,&vp);
  153.    MrgCop(&v);
  154.    lof2 = v.LOFCprList;    /* store pointers to copper lists for bitmap 2 */
  155.    shf2 = v.SHFCprList;
  156.    Disp2 = v.ViewPort->DspIns;
  157.  
  158.    LoadView(&v);           /* tell copper to use list for display */
  159.  
  160.    InitRastPort(&rp);      /* Initialize first RastPort   */
  161.    rp.BitMap = &b;         /* link rastport to bitmap 1   */
  162.    SetDrMd(&rp,JAM1);      /* set draw mode to JAM1       */
  163.  
  164.    InitArea(&myAreaInfo, areabuffer, 100);   /* Vertice buffer for Fill */
  165.    rp.AreaInfo = &myAreaInfo;
  166.  
  167.    rastpoint = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
  168.    InitTmpRas(&tmpras, rastpoint, RASSIZE(WIDTH,HEIGHT));
  169.    rp.TmpRas = &tmpras;
  170.  
  171.    InitRastPort(&rp2);   /* Do same for second RastPort */
  172.    rp2.BitMap = &b2;     /* link rastport to bitmap     */
  173.    SetDrMd(&rp2,JAM1);   /* set draw mode to JAM1       */
  174.  
  175.    InitArea(&myAreaInfo2, areabuffer2, 100);  /* Vertice buffer for Fill */
  176.    rp2.AreaInfo = &myAreaInfo2;
  177.  
  178.    rastpoint2 = (PLANEPTR)AllocRaster(WIDTH,HEIGHT);
  179.    InitTmpRas(&tmpras2, rastpoint2, RASSIZE(WIDTH,HEIGHT));
  180.    rp2.TmpRas = &tmpras2;
  181.  
  182. /*--- Set outline colors and clear bitmaps. */
  183.  
  184.    SetOPen(&rp,0);       /* set outline color */
  185.    SetOPen(&rp2,0);      /* set outline color */
  186.    Enable_Abort = 0;     /* disable automatic CTRL-C abort */
  187.    SetRast(&rp2,0);      /* clear bitmap 2 */
  188.    SetRast(&rp,0);       /* clear bitmap 1 */
  189.  
  190. /*--- Set up positions, sizes, and directions for balls. */
  191.  
  192.    for(i=0; i<30; i++)
  193.    {
  194.       bx[i] = RangeRand(239) + 40;  /* pick an initial location inside */
  195.       by[i] = RangeRand(119) + 40;  /* the clipping range.             */
  196.       bz[i] = RangeRand(239) + 40;
  197.       dx[i] = RangeRand(30) - 15;
  198.       dy[i] = RangeRand(30) - 15;
  199.       dz[i] = RangeRand(30) - 15;
  200.       if(dx[i] == 0)dx[i] = 10;     /* zero dx not allowed */
  201.       if(dy[i] == 0)dy[i] = 10;
  202.       if(dz[i] == 0)dz[i] = 10;
  203.       size[i] =  (319-bz[i])/12+ 1;      /* ball size is a function of z */
  204.    }
  205.  
  206.    for(k=0; k<30; k++)    /* Initialize cube parameters */
  207.    {
  208.       icol[k] = RangeRand(6) + 7;
  209.    }
  210.  
  211. /*--- Swap buffers, alternately drawing into each */
  212.  
  213.    ncol = 0;
  214.    nobj = 3;
  215.    for(i=0; i<100000; i++)
  216.    {
  217.       if(0 != Chk_Abort())   /* check for CTRL-C abort */
  218.       {
  219.          goto dats_all;
  220.       }
  221.  
  222.       v.LOFCprList = lof1;   /* set pointers to copper lists and */
  223.       v.SHFCprList = shf1;   /* set RastPort bitmap pointer      */
  224.       v.ViewPort->DspIns = Disp1;
  225.       WaitBOVP(&vp);         /* wait till in vertical blank area */
  226.       LoadView(&v);          /* display bitmap 1 */
  227.       if(i < 100)SetRast(&rp2,0);       /* clear bitmap 2 */
  228.  
  229.       if(i > 250)
  230.       {
  231.          tmp = colortable[0];   /* rotate colors */
  232.          for(j=0; j<15; j++)
  233.          {
  234.             colortable[j] = colortable[j+1];
  235.          }
  236.          colortable[15] = tmp;
  237.       }
  238.       if(i > 200)ncol = RangeRand(15);
  239.       colortable[ncol] = (colortable[ncol] + icl[RangeRand(8)]) & 0x0FFF;
  240.       if(i > 150)LoadRGB4(&vp,colortable,COLORS);  /* Set viewport colors */
  241.  
  242.       if(i < 200)
  243.       {
  244.          SetAPen(&rp2,14);       /* Set wall color */
  245.          AreaMove(&rp2, 0, 0);
  246.          AreaDraw(&rp2, 0, 199);
  247.          AreaDraw(&rp2, 80, 150);
  248.          AreaDraw(&rp2, 80, 50);
  249.          AreaEnd(&rp2);
  250.  
  251.          SetAPen(&rp2,11);       /* Set wall color */
  252.          AreaMove(&rp2, 319, 0);
  253.          AreaDraw(&rp2, 319, 199);
  254.          AreaDraw(&rp2, 240, 150);
  255.          AreaDraw(&rp2, 240, 50);
  256.          AreaEnd(&rp2);
  257.  
  258.          SetAPen(&rp2,15);       /* Set floor/ceiling color */
  259.          AreaMove(&rp2, 0, 0);
  260.          AreaDraw(&rp2, 80, 50);
  261.          AreaDraw(&rp2, 240, 50);
  262.          AreaDraw(&rp2, 319, 0);
  263.  
  264.          AreaMove(&rp2, 0, 199);
  265.          AreaDraw(&rp2, 80, 150);
  266.          AreaDraw(&rp2, 240, 150);
  267.          AreaDraw(&rp2, 319, 199);
  268.          AreaEnd(&rp2);
  269.       }
  270.  
  271. /*      if(i < 150)     /* start with one object, then go to three */
  272.          nobj = 3;
  273.       else
  274.          nobj = 10;
  275. */
  276.       for(k=0; k<nobj; k++)     /* move and draw balls */
  277.       {
  278.          bx[k] = bx[k] + dx[k];   /* increment positions. */
  279.          by[k] = by[k] + dy[k];
  280.          bz[k] = bz[k] + dz[k];
  281.          size[k] = (319-bz[k])/12 + 1;
  282.  
  283.      if(bx[k]+size[k] > 319) /* clip & change direction. */
  284.          {
  285.             bx[k] = 319 - size[k];
  286.             dx[k] = RangeRand(10) - 11;  /* set negative dx */
  287.          }
  288.      if(by[k]+size[k] > 199)
  289.          {
  290.             by[k] = 199 - size[k];
  291.             dy[k] = RangeRand(10) - 11;
  292.          }
  293.      if(bz[k] > 319)
  294.          {
  295.             bz[k] = 319;
  296.             dz[k] = RangeRand(10) - 11;
  297.          }
  298.      if(bx[k]-size[k] < 0)
  299.          {
  300.             bx[k] = size[k];
  301.             dx[k] = RangeRand(10) + 1;   /* set positive dx */
  302.          }
  303.      if(by[k]-size[k] < 0)
  304.          {
  305.             by[k] = size[k];
  306.             dy[k] = RangeRand(10) + 1;
  307.          }
  308.      if(bz[k] < 20)
  309.          {
  310.             bz[k] = 20;
  311.             dz[k] = RangeRand(10) + 1;
  312.          }
  313.  
  314.          cx = bx[k];
  315.          cy = by[k];
  316.          cz = bz[k];
  317.  
  318.          perspective(&cx, &cy, &cz);  /* do perspective xform */
  319.  
  320.          half = size[k]/2;
  321.          icol[k] = icol[k] - 1;
  322.          if(icol[k] < 7)icol[k] = 13;
  323.          icol2 = icol[k] - 7;
  324.          dxhalf = scl[icol2]*half;
  325.          xhalf = cx - dxhalf + icol2*dxhalf/3;
  326.          xminus = cx-dxhalf;
  327.          xplus = cx+dxhalf;
  328.          yminus = cy-half;
  329.          yplus = cy+half;
  330.  
  331.          SetAPen(&rp2,icol2);         /* Set color to show rotation */
  332.          AreaMove(&rp2, xminus, yminus);
  333.          AreaDraw(&rp2, xhalf, yminus);
  334.          AreaDraw(&rp2, xhalf, yplus);
  335.          AreaDraw(&rp2, xminus, yplus);
  336.          AreaEnd(&rp2);
  337.  
  338.          SetAPen(&rp2,icol[k]);         /* Set color to show rotation */
  339.          AreaMove(&rp2, xhalf, yminus);
  340.          AreaDraw(&rp2, xplus, yminus);
  341.          AreaDraw(&rp2, xplus, yplus);
  342.          AreaDraw(&rp2, xhalf, yplus);
  343.          AreaEnd(&rp2);
  344.       }
  345.  
  346.       v.LOFCprList = lof2;   /* set pointers to copper lists and */
  347.       v.SHFCprList = shf2;   /* set RastPort bitmap pointer      */
  348.       v.ViewPort->DspIns = Disp2;
  349.       WaitBOVP(&vp);         /* wait till in vertical blank area */
  350.       LoadView(&v);          /* display bitmap 2 */
  351.       if(i < 100)SetRast(&rp,0);        /* clear bitmap 1 */
  352.  
  353.       if(i > 150)LoadRGB4(&vp,colortable,COLORS);  /* Set viewport colors */
  354.  
  355.       if(i < 200)
  356.       {
  357.          SetAPen(&rp,14);       /* Set wall color */
  358.          AreaMove(&rp, 0, 0);
  359.          AreaDraw(&rp, 0, 199);
  360.          AreaDraw(&rp, 80, 150);
  361.          AreaDraw(&rp, 80, 50);
  362.          AreaEnd(&rp);
  363.  
  364.          SetAPen(&rp,11);       /* Set wall color */
  365.          AreaMove(&rp, 319, 0);
  366.          AreaDraw(&rp, 319, 199);
  367.          AreaDraw(&rp, 240, 150);
  368.          AreaDraw(&rp, 240, 50);
  369.          AreaEnd(&rp);
  370.  
  371.          SetAPen(&rp,15);       /* Set floor color */
  372.          AreaMove(&rp, 0, 0);
  373.          AreaDraw(&rp, 80, 50);
  374.          AreaDraw(&rp, 240, 50);
  375.          AreaDraw(&rp, 319, 0);
  376.  
  377.          AreaMove(&rp, 0, 199);
  378.          AreaDraw(&rp, 80, 150);
  379.          AreaDraw(&rp, 240, 150);
  380.          AreaDraw(&rp, 319, 199);
  381.          AreaEnd(&rp);
  382.       }
  383.  
  384.       for(k=0; k<nobj; k++)       /* draw a boxes spinning and others */
  385.       {
  386.          bx[k] = bx[k] + dx[k];   /* increment positions. */
  387.          by[k] = by[k] + dy[k];
  388.          bz[k] = bz[k] + dz[k];
  389.          size[k] = (319-bz[k])/12 + 1;
  390.  
  391.      if(bx[k]+size[k] > 319) /* clip & change direction. */
  392.          {
  393.             bx[k] = 319 - size[k];
  394.             dx[k] = RangeRand(10) - 11;  /* set negative dx */
  395.          }
  396.      if(by[k]+size[k] > 199)
  397.          {
  398.             by[k] = 199 - size[k];
  399.             dy[k] = RangeRand(10) - 11;
  400.          }
  401.      if(bz[k] > 319)
  402.          {
  403.             bz[k] = 319;
  404.             dz[k] = RangeRand(10) - 11;
  405.          }
  406.      if(bx[k]-size[k] < 0)
  407.          {
  408.             bx[k] = size[k];
  409.             dx[k] = RangeRand(10) + 1;   /* set positive dx */
  410.          }
  411.      if(by[k]-size[k] < 0)
  412.          {
  413.             by[k] = size[k];
  414.             dy[k] = RangeRand(10) + 1;
  415.          }
  416.      if(bz[k] < 20)
  417.          {
  418.             bz[k] = 20;
  419.             dz[k] = RangeRand(10) + 1;
  420.          }
  421.  
  422.          cx = bx[k];
  423.          cy = by[k];
  424.          cz = bz[k];
  425.  
  426.          perspective(&cx, &cy, &cz);  /* do perspective xform */
  427.  
  428.          half = size[k]/2;
  429.          icol[k] = icol[k] - 1;
  430.          if(icol[k] < 7)icol[k] = 13;
  431.          icol2 = icol[k] - 7;
  432.          dxhalf = scl[icol2]*half;
  433.          xhalf = cx - dxhalf + icol2*dxhalf/3;
  434.          xminus = cx-dxhalf;
  435.          xplus = cx+dxhalf;
  436.          yminus = cy-half;
  437.          yplus = cy+half;
  438.  
  439.          SetAPen(&rp,icol2);         /* Set color to show rotation */
  440.          AreaMove(&rp, xminus, yminus);
  441.          AreaDraw(&rp, xhalf, yminus);
  442.          AreaDraw(&rp, xhalf, yplus);
  443.          AreaDraw(&rp, xminus, yplus);
  444.          AreaEnd(&rp);
  445.  
  446.          SetAPen(&rp,icol[k]);         /* Set color to show rotation */
  447.          AreaMove(&rp, xhalf, yminus);
  448.          AreaDraw(&rp, xplus, yminus);
  449.          AreaDraw(&rp, xplus, yplus);
  450.          AreaDraw(&rp, xhalf, yplus);
  451.          AreaEnd(&rp);
  452.       }
  453.  
  454.    }
  455.  
  456. dats_all:
  457.  
  458.    ON_SPRITE;                /* turn on pointer (sprites on) */
  459.    LoadView(oldview);        /* put back the old view */
  460.    FreeMemory();             /* exit gracefully */
  461.    CloseLibrary(GfxBase);    /* since opened library, close it */
  462. }
  463.  
  464. /* End of main ----------------------------------------------------------*/
  465.  
  466. /* return user and system-allocated memory to sys manager */
  467. FreeMemory()
  468. {
  469.    int i;
  470.  
  471.    FreeRaster(rastpoint,WIDTH,HEIGHT);   /* Free drawing areas */
  472.    FreeRaster(rastpoint2,WIDTH,HEIGHT);
  473.    for(i=0; i<DEPTH; i++)                /* Free bitmap RAM */
  474.    {
  475.       FreeRaster(b.Planes[i],WIDTH,HEIGHT);
  476.       FreeRaster(b2.Planes[i],WIDTH,HEIGHT);
  477.    }
  478.    FreeColorMap(cm);                      /* Free colormap */
  479.    v.LOFCprList = lof1;                   /* Free Copper structures */
  480.    v.SHFCprList = shf1;
  481.    FreeVPortCopLists(&vp);
  482.    FreeCprList(v.LOFCprList);
  483.    FreeCprList(v.SHFCprList);             /* Free interlace copper lists */
  484.    v.LOFCprList = lof2;
  485.    v.SHFCprList = shf2;
  486.    FreeVPortCopLists(&vp);
  487.    FreeCprList(v.LOFCprList);
  488.    FreeCprList(v.SHFCprList);
  489.    return(0);
  490. }
  491.  
  492. int perspective(x, y, z)
  493. SHORT *x, *y, *z;
  494. {
  495.    static float eye_x = 160., eye_y = 100., eye_z = -320.;  /* set viewpoint */
  496.    static float range, sclx = 319., scly = 319.;       /* set scale factor */
  497.  
  498.    range = *z - eye_z;
  499.    if(range != 0)
  500.    {
  501.       *x = (SHORT)(eye_x + sclx * ((float)*x-eye_x)/range);
  502.       *y = (SHORT)(eye_y + scly * ((float)*y-eye_y)/range);
  503. /*      *z = (SHORT)(1. * (float)*z);  */
  504.    }
  505. }
  506.